//
//  basic_interactive.cpp
//  GLDemo
//
//  Created by wenqi on 6/4/14.
//  Copyright (c) 2014 xiewneqi. All rights reserved.
//

#ifdef __APPLE__
#include <GLUT/glut.h>
#define glGenVertexArrays glGenVertexArraysAPPLE
#define glBindVertexArray glBindVertexArrayAPPLE
#else
#include "GL/glew.h"
#include "GL/glut.h"
#endif

#include "shader_initialize.h"
#include "basic_interactive.h"
#include "vector3.h"
#include <cmath>

static GLuint vbos[1];
static GLuint vaos[1];

static Vector3 vertices[3] =
{
    Vector3 (-0.5, -0.5, 0),
    Vector3 (0.5, -0.5, 0),
    Vector3 (0, 0.5, 0)
};

float angle = 0.05 * M_PI / 180;

void init_basic_interactive_main (int argc, char** argv)
{
    glutInit (&argc, argv);
    glutInitDisplayMode (GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
    glutInitWindowSize (800, 600);
    glutInitWindowPosition (100, 100);
    glutCreateWindow ("Hello, interactive demo");
    glutDisplayFunc (display_basic_interactive);
    glutIdleFunc (idle_basic_interactive);
    init_basic_interactive_gl ();
    
    int sub_menu = glutCreateMenu (sub_menu_function);
    glutAddMenuEntry ("Start", 1);
    glutAddMenuEntry ("Stop", 2);
    glutCreateMenu (top_menu_function);
    glutAddMenuEntry ("Quit", 1);
    glutAddSubMenu ("Rotation", sub_menu);
    glutAttachMenu (GLUT_RIGHT_BUTTON);
    
    glutMainLoop ();
}

void init_basic_interactive_gl ()
{
    // set gl states
    glEnable (GL_DEPTH_TEST);
    glDepthFunc (GL_GEQUAL);
    glClearDepth (0);
    glClearColor (1, 1, 1, 1);
    
    // setup data
    glGenBuffers (1, vbos);
    glGenVertexArrays (1, vaos);
    GLuint shaderProgram = InitShader ("vbo_vao_vertex_shader.glsl", "vbo_vao_fragment_shader.glsl");
    glUseProgram (shaderProgram);
    GLuint posLoc = glGetAttribLocation (shaderProgram, "va_position");
    
    glBindBuffer (GL_ARRAY_BUFFER, vbos[0]);
    glBufferData (GL_ARRAY_BUFFER, sizeof (vertices), vertices, GL_STATIC_DRAW);
    
    glBindVertexArray (vaos[0]);
    glEnableVertexAttribArray (posLoc);
    glBindBuffer (GL_ARRAY_BUFFER, vbos[0]);
    glVertexAttribPointer (posLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
}

void display_basic_interactive ()
{
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glBindVertexArray (vaos[0]);
    glDrawArrays (GL_TRIANGLES, 0, 3);
    glutSwapBuffers ();
}

void idle_basic_interactive ()
{
    for( int i = 0; i < 3; i++)
    {
        float x = cos(angle)*vertices[i].GetX () - sin(angle)*vertices[i].GetY ();
        float y = sin(angle)*vertices[i].GetX () + cos(angle)*vertices[i].GetY ();
        vertices[i].Set (x, y, vertices[i].GetZ ());
    }
    
    glBindBuffer (GL_ARRAY_BUFFER, vbos[0]);
    glBufferData (GL_ARRAY_BUFFER, sizeof (vertices), vertices, GL_STATIC_DRAW);

    glutPostRedisplay ();
}

void top_menu_function (int id)
{
    if (id == 1)
    {
        exit (0);
    }
    glutPostRedisplay ();
}

void sub_menu_function (int id)
{
    switch (id)
    {
        case 1:
            glutIdleFunc (idle_basic_interactive);
            break;
            
        case 2:
            glutIdleFunc (NULL);
            break;
    }
    glutPostRedisplay ();
}


